An AI-powered agent and Claude Code plugin that runs comprehensive security scanning and code quality analysis on your codebase.
Install as a Claude Code plugin with one command:
# In Claude Code, run:
/plugin add github://ehntec/security-agentOr clone and install locally:
git clone https://github.com/ehntec/security-agent.git
cd security-agent
uv sync # Install Python dependenciesThen in Claude Code:
/plugin add /path/to/security-agentAfter installation, these slash commands are available:
| Command | Description |
|---|---|
/security-agent:scan [path] |
Full security + quality scan |
/security-agent:security-scan [path] |
Security only (Semgrep, Bandit, Trivy) |
/security-agent:quality-scan [path] |
Quality only (Mypy, Radon, Vulture) |
/security-agent:setup |
Install all dependencies |
- Semgrep - Multi-language SAST (Static Application Security Testing)
- Bandit - Python-specific security linter
- Trivy - Vulnerabilities, secrets, and IaC misconfigurations
- Mypy - Static type checker
- Radon - Code complexity analysis
- Vulture - Dead code detection
- Pydocstyle - Docstring convention checker
- Pytest - Test runner with coverage
- Git Pre-commit Hook - Configurable scanning before commits
- Claude Code Hooks - Automatic scanning when AI agents edit code
- CLI Scanner - Manual scanning of files and directories
# Install Python dependencies
uv sync
# Or with pip
pip install -e .
# Install git hooks
python scripts/install-hooks.py| Tool | Install | Purpose |
|---|---|---|
| Trivy | See below | SCA, secrets, misconfig |
Install Trivy:
# Windows (scoop)
scoop install trivy
# Windows (chocolatey)
choco install trivy
# macOS
brew install trivy
# Linux
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/binAll Python tools (semgrep, bandit, mypy, etc.) are installed automatically via uv sync.
All settings are in config.toml:
[agent]
model = "haiku" # haiku, sonnet, or opus
[hooks]
mode = "always" # "always" or "verify_only"
[security.semgrep]
config = "auto" # auto, p/security-audit, p/python, etc.
[security.bandit]
severity = "ll" # l (low+), ll (medium+), lll (high only)
[security.trivy]
scanners = "all" # vuln, secret, config, all
[security.exclusions]
exclude_env_files = true # Skip .env files from scanning
[quality.mypy]
strict = true
[quality.radon]
min_grade = "C" # A-F
[quality.vulture]
min_confidence = 80 # 0-100
[quality.pydocstyle]
convention = "google" # google, numpy, pep257
[quality.pytest]
run_tests = trueuv run python main.pyYou'll be prompted to:
- Enter the path to scan
- Select scan type
==================================================
SECURITY & CODE QUALITY AGENT
==================================================
Enter path to scan: /path/to/project
Select scan type:
COMBINED:
1. ALL - Security + Code Quality (comprehensive)
SECURITY ONLY:
2. SECURITY - Semgrep + Bandit + Trivy
3. SAST - Semgrep + Bandit (code analysis)
4. TRIVY - Trivy only (SCA + secrets)
CODE QUALITY ONLY:
5. QUALITY - Mypy + Radon + Vulture
6. MYPY - Type checking
7. COMPLEXITY - Code complexity analysis
8. TESTS - Run pytest with coverage
Enter choice [1-8] (default: 1):
# Full scan (security + quality)
python src/scanner.py path/to/code
# Security only
python src/scanner.py --type security path/to/code
# Code quality only
python src/scanner.py --type quality path/to/code
# JSON output
python src/scanner.py --json path/to/code
# Fail on high/critical issues (for CI)
python src/scanner.py --fail-on-findings path/to/code
# Trivy only
python src/scanner.py --trivy-only path/to/code
python src/scanner.py --trivy-only --trivy-type vuln path/to/codeInstall the hook and git alias:
python scripts/install-hooks.pyConfigure in config.toml:
| Mode | Behavior |
|---|---|
mode = "always" |
Run checks on every commit |
mode = "verify_only" |
Only run checks with git verify |
# Normal commit (skips checks if mode=verify_only)
git commit -m "quick fix"
# Commit WITH security/quality checks
git verify -m "important changes"
# Bypass all checks (not recommended)
git commit --no-verify -m "emergency fix"Security Checks (blocking):
- Semgrep - SAST vulnerabilities
- Bandit - Python security issues
- Trivy - Secrets and dependency vulnerabilities
Code Quality Checks:
- Mypy - Type errors (blocking)
- Radon - Complexity (warning only)
- Vulture - Dead code (warning only)
The .claude/settings.json configures automatic scanning when Claude Code edits files:
{
"hooks": {
"PostToolUse": [
{ "matcher": "Edit", "command": "python src/hook_handler.py" },
{ "matcher": "Write", "command": "python src/hook_handler.py" }
]
}
}| Type | Tools | Use Case |
|---|---|---|
ALL |
All tools | Comprehensive analysis |
SECURITY |
Semgrep + Bandit + Trivy | Security-focused |
SAST |
Semgrep + Bandit | Code vulnerabilities |
TRIVY |
Trivy | Dependencies + secrets |
QUALITY |
Mypy + Radon + Vulture | Code quality |
MYPY |
Mypy | Type checking |
COMPLEXITY |
Radon | Complexity analysis |
TESTS |
Pytest | Tests + coverage |
- Purpose: Pattern-based SAST for multiple languages
- Configs:
auto,p/security-audit,p/python,p/javascript,p/owasp-top-ten - Finds: SQL injection, XSS, command injection, insecure patterns
- Purpose: Python-specific security linter
- Severity:
-l(low+),-ll(medium+),-lll(high only) - Finds: Hardcoded passwords, shell injection, unsafe deserialization
| Scan Type | Detects |
|---|---|
vuln |
Dependency vulnerabilities (CVEs) |
secret |
Hardcoded secrets, API keys |
config |
IaC misconfigurations (Terraform, Docker, K8s) |
- Purpose: Static type checker for Python
- Modes: Default or
--strict - Finds: Type errors, missing annotations, incompatible types
- Purpose: Code complexity metrics
- Metrics: Cyclomatic complexity, maintainability index
- Grades: A (best) to F (worst), reports C and below by default
- Purpose: Dead code detection
- Confidence: 0-100% (default 80%)
- Finds: Unused functions, variables, imports, classes
- Purpose: Docstring convention checker
- Conventions:
google,numpy,pep257 - Checks: Missing docstrings, formatting issues
- Purpose: Test runner with coverage
- Coverage: Reports percentage and missing lines
- Output: Pass/fail counts, failure details
security-agent/
├── .claude-plugin/
│ └── plugin.json # Plugin metadata (required for distribution)
├── commands/ # Slash commands
│ ├── scan.md # /security-agent:scan
│ ├── security-scan.md # /security-agent:security-scan
│ ├── quality-scan.md # /security-agent:quality-scan
│ └── setup.md # /security-agent:setup
├── skills/
│ └── security-scanning/ # Auto-invoked security skill
│ └── SKILL.md
├── main.py # Interactive entry point
├── config.toml # All configuration options
├── src/
│ ├── core.py # Agent class and tool definitions
│ ├── config.py # Configuration loader
│ ├── scanner.py # Standalone CLI scanner
│ └── hook_handler.py # Claude Code hook handler
├── scripts/
│ ├── install-hooks.py # Git hook installer
│ └── verify-commit.py # Verified commit helper
├── hooks/
│ └── pre-commit # Pre-commit hook template
├── .claude/
│ └── settings.json # Claude Code hooks config
├── pyproject.toml # Dependencies
└── README.md
============================================================
SCAN RESULTS: 4 issue(s) found
============================================================
[HIGH]
- src/api.py:45 [bandit/security]
Rule: B105 (hardcoded_password_string)
Possible hardcoded password: 'secret123'
CWE-259
- requirements.txt [trivy/vulnerability]
Rule: CVE-2023-1234
requests 2.28.0 -> 2.31.0
[MEDIUM]
- src/utils.py:12 [semgrep/security]
Rule: python.lang.security.audit.subprocess-shell-true
subprocess call with shell=True identified
[ERROR]
- src/handler.py:23 [mypy/type_error]
Rule: arg-type
Argument 1 has incompatible type "str"; expected "int"
MIT